#include "rs485_port_init.h"
#include "stm32f4xx.h"
void rs485_port_USART5_Init(uint32_t baudrate)
{
    //    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef uart;
    GPIO_InitTypeDef gpio;
    // 1. 使能时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);

    /* PC12 TX */
    gpio.GPIO_Pin = GPIO_Pin_12;
    gpio.GPIO_Mode = GPIO_Mode_AF;
    gpio.GPIO_OType = GPIO_OType_PP;
    gpio.GPIO_PuPd = GPIO_PuPd_UP;
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &gpio);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);

    /* PD2 RX */

    gpio.GPIO_Pin = GPIO_Pin_2;

    GPIO_Init(GPIOD, &gpio);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);

    uart.USART_BaudRate = baudrate;
    uart.USART_WordLength = USART_WordLength_8b;
    uart.USART_StopBits = USART_StopBits_1;
    uart.USART_Parity = USART_Parity_No;
    uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(UART5, &uart);

    /* 接收中断（可根据需要换成 IDLE / DMA） */
    USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
    NVIC_EnableIRQ(UART5_IRQn);

    USART_Cmd(UART5, ENABLE);
}

void rs485_port_oe_PA15_Init(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 使能 GPIOA 时钟

    // 1. 使能GPIOA时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    // 2. 解除PA15的JTAG复用锁定（关键步骤）
    // 禁用JTAG功能，保留SWD调试（不影响下载调试）
    //    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

    // 3. 配置PA15引脚参数
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;        // 选择PA15引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;     // 输出模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;    // 推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出速度50MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  // 无上下拉（根据需求调整）

    // 4. 应用配置到GPIOA
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 如需初始低电平：
    GPIO_ResetBits(GPIOA, GPIO_Pin_15);
}
void USART5_SendByte(uint8_t data)
{
    USART_SendData(UART5, data);
    while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET)
        ; // 等待发送完成
}

// 初始化TIM6定时器，配置为2ms定时
void receive_frame_timeout_timer_TIM6_init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 1. 开时钟 *************************************************************/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

    /* 2. 时基单元配置 *******************************************************/
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1;        // 84 MHz / 84 = 1 MHz
    TIM_TimeBaseStructure.TIM_Period    = 2000 - 1;      // 1 MHz / 2000 = 500 Hz (2 ms)
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

    /* 3. 中断配置 ***********************************************************/
		TIM_ClearITPendingBit(TIM6, TIM_IT_Update); // 清除中断标志
    TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = TIM6_DAC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* 4. 启动定时器 *********************************************************/
		
		TIM_SetCounter(TIM6, 0);
		TIM_ClearITPendingBit(TIM6, TIM_IT_Update); // 清除中断标志
    TIM_Cmd(TIM6, DISABLE);                  // 关闭定时器
}

void set_oe_to_send(void)
{
    GPIO_SetBits(GPIOA, GPIO_Pin_15);
}
void set_oe_to_receive(void)
{
    GPIO_ResetBits(GPIOA, GPIO_Pin_15);
}
void start_to_send(void)
{
    // usart_interrupt_enable(UART3, USART_INT_TBE); // 发送缓冲区空中断
    USART_ITConfig(UART5, USART_IT_TXE, ENABLE);
}
void stop_to_send(void)
{
    USART_ITConfig(UART5, USART_IT_TXE, DISABLE);
}
uint8_t check_receive_interrupt_registers_data(uint8_t *byte)
{
    if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
    {
        *byte = USART_ReceiveData(UART5);
        USART_ClearITPendingBit(UART5, USART_IT_RXNE);
        return 1;
    }
    return 0;
}
void start_receive_timeout_timer(void)
{
    TIM_SetCounter(TIM6, 0);
    TIM_Cmd(TIM6, ENABLE);
}
void enable_txe_empty_interrupt(void)
{
    USART_ITConfig(UART5, USART_IT_TXE, ENABLE);
}
void send_out_one_byte(uint8_t byte)
{
    while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET)
        ;
    USART_SendData(UART5, byte);
}
uint8_t check_txe_empty_interrupt(void)
{
    if (USART_GetITStatus(UART5, USART_IT_TXE) != RESET)
    { /* disable interrupt */
        USART_ClearITPendingBit(UART5, USART_IT_TXE);
        USART_ITConfig(UART5, USART_IT_TXE, DISABLE);
        return 1;
    }
    return 0;
}
void enable_wait_tc_empty_interrupt(void)
{
    USART_ITConfig(UART5, USART_IT_TC, ENABLE);
}
uint8_t check_tc_empty_interrupt(void)
{
    if (USART_GetITStatus(UART5, USART_IT_TC) != RESET)
    { /* disable interrupt */
        USART_ClearITPendingBit(UART5, USART_IT_TC);
        USART_ITConfig(UART5, USART_IT_TC, DISABLE);
        return 1;
    }
    return 0;
}
uint8_t check_receive_timeout_timer_interrput(void)
{
    if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
    {
        /* disable interrupt */
        TIM_Cmd(TIM6, DISABLE);                  // 关闭定时器
        TIM_SetCounter(TIM6, 0);                        // 清计数器
        TIM_ClearITPendingBit(TIM6, TIM_IT_Update); // 清除中断标志
        /* enable interrupt */
        return 1;
    }
    return 0;
}

void rs485_hard_init(void)
{
    receive_frame_timeout_timer_TIM6_init();
    rs485_port_USART5_Init(9600);
    rs485_port_oe_PA15_Init();
    set_oe_to_receive();
}
